﻿using LTKJ.DataBase;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Windows.Forms;

namespace LTKJ.RTU
{
    class socketUtil
    {
        public static int port;
        public static Socket socket;
        public static Dictionary<string, Session> sessionPool = new Dictionary<string, Session>();


        #region 启动WebSocket服务
        /// <summary>
        /// 启动WebSocket服务
        /// </summary>
        public static void listenInit(int port)
        {
            socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            socket.Bind(new IPEndPoint(IPAddress.Any, port));
            socket.Listen(20);
            socket.BeginAccept(new AsyncCallback(Accept), socket);
         //   ShowMessageInWindow("启动端口 "+port.ToString()+"监听");
        }
        #endregion

        #region 处理客户端连接请求
        /// <summary>
        /// 处理客户端连接请求
        /// </summary>
        /// <param name="result"></param>
        public static void Accept(IAsyncResult socket)
        {
            // 还原传入的原始套接字
            Socket SockeServer = (Socket)socket.AsyncState;
            // 在原始套接字上调用EndAccept方法，返回新的套接字
            Socket SockeClient = SockeServer.EndAccept(socket);
            byte[] buffer = new byte[4096];
            try
            {
                //接收客户端的数据
                SockeClient.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), SockeClient);
                //保存登录的客户端
                Session session = new Session();
                session.SockeClient = SockeClient;
                IPEndPoint ip = (IPEndPoint)SockeClient.RemoteEndPoint;
                string AdrFamily = ip.AddressFamily.ToString();//地址类型
                string IpStr = ip.Address.ToString();//IP地址点分表达方式
                string IpPort = ip.Port.ToString();//IP地址端口  
                session.IP = IpStr;
                session.buffer = buffer;
                lock (sessionPool)
                {
                    if (sessionPool.ContainsKey(session.IP))
                    {
                        sessionPool.Remove(session.IP);
                    }
                       sessionPool.Add(session.IP, session);
                }
                //准备接受下一个客户端
                SockeServer.BeginAccept(new AsyncCallback(Accept), SockeServer);
             //   ShowMessageInWindow(string.Format("Client {0} connected", SockeClient.RemoteEndPoint));
            }
            catch (Exception ex)
            {
              //   ShowMessageInWindow("Error : " + ex.ToString());
            }
        }
        #endregion

        #region 处理接收的数据
        /// <summary>
        /// 处理接受的数据
        /// </summary>
        /// <param name="socket"></param>
        public static void Recieve(IAsyncResult socket)
        {
            Socket SockeClient = (Socket)socket.AsyncState;
            IPEndPoint ip = (IPEndPoint)SockeClient.RemoteEndPoint;
            string AdrFamily = ip.AddressFamily.ToString();//地址类型
            string IpStr = ip.Address.ToString();//IP地址点分表达方式
            string IpPort = ip.Port.ToString();//IP地址端口 
            string IP = IpStr;
            try
            {
                if (SockeClient == null || !SockeClient.Connected)
                {
                    return;
                }

                int length = SockeClient.EndReceive(socket);
                if (length == 0) return;
                byte[] buffer = sessionPool[IP].buffer;
                string msg = Common.ByteArrayToHexString(buffer, 0, length);
                msg = msg.Replace(" ", "");
             //   ShowMessageInWindow("返回数据 " + msg);
                int msgLength = msg.Length;

                if (sessionPool.ContainsKey(IP) && msgLength == 58)
                {

                    ModelDevice mod = new ModelDevice();
                    Object id = DbHelper.GetSingle("select id from tran_point where ip='" + ip + "'");
                    if (id == null) { return; }
                    string machine_id = id.ToString();
                    Object name = DbHelper.GetSingle("select name from tran_point where serial='" + ip + "'");
                    string machine_name = name.ToString();
                    mod.DeviceId = machine_id;
                    mod.DeviceName = machine_name;
                    string s = msg.Substring(6, 48);
                    mod.Temperature1 = int.Parse(s.Substring(0, 4)) / (double)1000;
                    mod.Temperature2 = int.Parse(s.Substring(8, 4)) / (double)1000;
                    mod.Pressure1 = int.Parse(s.Substring(16, 4)) / (double)1000;
                    mod.Pressure2 = int.Parse(s.Substring(24, 4)) / (double)1000;
                    mod.waterContent1 = int.Parse(s.Substring(32, 4)) / (double)1000;
                    mod.waterContent2 = int.Parse(s.Substring(40, 4)) / (double)1000;
                //    AddRunData(mod, true);
                }

                if (sessionPool.ContainsKey(IP) && msgLength == 42)
                {
                  //  ShowMessageInWindow("心跳包为 " + sessionPool[IP].HeartBeat + "返回数据为" + msg);
                    ModelDevice mod = new ModelDevice();
                    Object id = DbHelper.GetSingle("select id from tran_point where ip='" + ip + "'");
                    if (id == null) { return; }
                    string machine_id = id.ToString();
                    Object name = DbHelper.GetSingle("select name from tran_point where ip='" + ip + "'");
                    string machine_name = name.ToString();
                    mod.DeviceId = machine_id;
                    mod.DeviceName = machine_name;
                    string s = msg.Substring(6, 32);
                    string flow1Str = s.Substring(4, 4) + s.Substring(0, 4);
                    mod.Flow1 = int.Parse(flow1Str) / (double)1000;
                    string flow2Str = s.Substring(20, 4) + s.Substring(16, 4);
                    mod.Flow2 = int.Parse(flow2Str) / (double)1000;
                 //   AddFlowRunData(mod, true);
                }
                SockeClient.BeginReceive(buffer, 0, buffer.Length, SocketFlags.None, new AsyncCallback(Recieve), SockeClient);
            }
            catch (Exception ex)
            {
                SockeClient.Disconnect(true);
               //ShowMessageInWindow(string.Format("客户端 {0} 断开连接 {1}", IP, ex.Message));
                sessionPool.Remove(IP);
            }
        }

        /// <summary>
        /// 发送消息
        /// </summary>
        /// <param name="s_socket">指定客户端socket</param>
        /// <param name="bytes">发送消息</param>
        public static void Send(Socket c_socket, byte[] bytes)
        {
            try
            {
                //发送
                c_socket.BeginSend(bytes, 0, bytes.Length, SocketFlags.None, asyncResult =>
                {
                    try
                    {
                        //完成消息发送
                        int len = c_socket.EndSend(asyncResult);
                    }
                    catch (Exception ex)
                    {
                        if (c_socket != null)
                        {
                            c_socket.Close();
                            c_socket = null;
                        }
                        Console.WriteLine("error ex=" + ex.Message + " " + ex.StackTrace);
                    }
                }, null);

            }
            catch (Exception ex)
            {
                if (c_socket != null)
                {
                    c_socket.Close();
                    c_socket = null;
                }
            }
        }

        #endregion
    }
}
